/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

/* eslint-disable @typescript-eslint/no-shadow */
import React, { useEffect, useState, useRef } from 'react';
import { getChildrenArea } from '@/services/jdk';
import { Spin, Cascader, message } from 'antd';
import type { BaseOptionType } from 'antd/es/cascader';
import find from 'lodash/find';
import { merge } from 'lodash';

const { SHOW_CHILD } = Cascader;
interface Options {
  label: string;
  value: string | string[];
  id?: string;
  pid?: string;
  isLeaf?: boolean;
  disabled?: boolean;
  checked?: boolean;
  children?: any;
  text?: string;
}

function arrPop(data: any, len: number) {
  return data.map((item: any) => item.slice(0, len));
}

type KbAddressSelectProps = {
  name?: string;
  label?: string;
  level?: number;
  multiple?: boolean;
  multipleDisabled?: boolean;
  allowClear?: boolean;
  disabled?: boolean;
  value?: (string | number | (string[] | number[]))[];
  defaultOptions?: Options[];
  placeholder?: string;
  onChange?: (value: (string | number)[], options: any) => void;
  children?: any;
  onDropdownVisibleChange?: (status: boolean) => void;
  [name: string]: any;
};

const KbAddressSelect: React.FC<KbAddressSelectProps> = (props) => {
  const {
    level = 3,
    disabled,
    multiple,
    value: initValue,
    onChange,
    value,
    multipleDisabled,
    defaultOptions,
    ...rest
  } = props;
  const [addressLoading, setAddressLoading] = useState<boolean>(false);
  const [options, setOptions] = useState<Options[]>([]);
  const count = useRef<number>(0);

  const mapOption = ({
    defOptions,
    key,
    data,
  }: {
    defOptions: Options[];
    key: string;
    data: Options[];
  }): Options[] => {
    return defOptions.map((item: Options) => {
      const disabledValue: string[] = Array.from({ length: level }, (v, k) => value[0][k]);
      item.disabled = multipleDisabled && !disabledValue.includes(item.value);
      if (key == item.value) {
        return {
          ...item,
          children: data,
        };
      }
      if (item.children) {
        return {
          ...item,
          children: mapOption({
            defOptions: item.children,
            key,
            data,
          }),
        };
      }
      return item;
    });
  };

  const formatOptions = (arr: any[] = []) => {
    return merge([], options, arr);
  };

  const handleDropdownVisibleChange = (open: boolean) => {
    if (open) {
      getChildrenArea({ id: 0 }, level == 0).then((res) => {
        setAddressLoading(false);
        console.log('handleDropdownVisibleChange', [...options]);
        setOptions(
          formatOptions(
            res.map((item) => {
              const ditem = defaultOptions
                ? find(defaultOptions, (di) => di.value === item.value)
                : null;
              return ditem || item;
            }),
          ),
        );
      });
    }
  };

  const addressChecked = (data: string[][], level: number) =>
    data.map((item) => item.length !== level + 1).includes(true);

  const onCascaderChange = (value: any[], options: any) => {
    if (multiple && value.length > 0 && multipleDisabled) {
      const checdedStatus: boolean = addressChecked(value, level);
      if (checdedStatus) {
        message.error('请选择对应等级地址');
        return;
      }
      const defValue = arrPop(value, level);
      const multipleList: any[] = [];
      defValue.forEach((item: string[]) => {
        const defItem = defValue[0];
        multipleList.push(
          item.map((item1: any, index1: any) => item1 === defItem[index1]).includes(false),
        );
      });
      if (multipleList.includes(true)) {
        message.error('对应等级下区域支持多选');
        return;
      }
    }
    if (onChange) {
      onChange(value, options);
    }
  };

  const getData = (option: Options[] = [], data: Options[]) =>
    data.map((item) => find(option, (di) => di.value === item.value) || item);

  const loadData = (selectedOptions: BaseOptionType) => {
    const targetOption = selectedOptions[selectedOptions.length - 1];
    if (targetOption?.children?.length) {
      setOptions([...options]);
      return;
    }
    targetOption.loading = true;
    const isLeaf = selectedOptions.length >= level;
    getChildrenArea({ id: targetOption.value }, isLeaf).then((data) => {
      targetOption.loading = false;
      targetOption.children = getData(
        find(defaultOptions, (di) => di.value === targetOption.value)?.children,
        data,
      );
      setOptions([...options]);
    });
  };

  const getAddressList = (
    defOptions: any,
    param: string[],
    count_: number,
    addressLevel: number,
  ) => {
    let op_ = defOptions;
    const isLeaf = addressLevel == count_;
    if (count_ > param.length - 2) {
      setAddressLoading(false);
      return;
    }
    getChildrenArea({ id: param[count_] }, isLeaf).then((data) => {
      if (!data.length) return;
      // 设置初始值
      if (defOptions.length == 0) {
        op_ = data;
      }
      count.current += 1;
      op_ = mapOption({ defOptions: op_, key: param[count_], data });
      setOptions(op_);
      getAddressList(op_, param, count_ + 1, addressLevel);
    });
  };

  useEffect(() => {
    const arr = multiple ? (initValue ? initValue[0] || [] : []) : initValue || [];
    const value = ['0', ...(arr as string[])];
    if (defaultOptions) {
      setOptions(defaultOptions);
    } else {
      setAddressLoading(true);
      getAddressList(options, value, count.current, level as number);
    }
    return () => {
      count.current = 0;
    };
  }, [level, multiple, defaultOptions]);

  return (
    <Spin spinning={addressLoading}>
      <Cascader
        popupClassName={`cascaderStorey__${level}`}
        value={initValue}
        disabled={disabled}
        options={options}
        changeOnSelect={!multiple}
        multiple={multiple}
        maxTagCount='responsive'
        showCheckedStrategy={SHOW_CHILD}
        onDropdownVisibleChange={handleDropdownVisibleChange}
        onChange={onCascaderChange}
        loadData={loadData}
        {...rest}
      />
    </Spin>
  );
};

export default React.memo(KbAddressSelect, () => false);
